import json
from flask import Flask, render_template, request, jsonify, redirect, url_for, send_file
from werkzeug.utils import secure_filename
import os
from datetime import datetime

app=Flask(__name__)
# bootstrap = Bootstrap(app)

# 配置config全局设置
class Config(object):
    SQLALCHEMY_DATABASE_URI = "1"
    SQLALCHEMY_TRACK_MODIFICATIONS = False
    SQLALCHEMY_ECHO = True

app.config['UPLOAD_FOLDER'] = 'uploads/'
app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 0

class ESP32State:
    def __init__(self, id = None) -> None:
        self.id = None
        self.moist = None
        self.moist_s = None
        self.light = None
        self.light_s = None
        self.tmpre = None
        self.tmpre_s = None
        self.auto = None
        self.cmd = None
    
    def processJsonData(self, jsonData:dict) -> None:
        self.id = jsonData["id"]
        self.moist = jsonData["moist"]
        self.moist_s = jsonData["moist_s"]
        self.light = jsonData["light"]
        self.light_s = jsonData["light_s"]
        self.tmpre = jsonData["tmpre"]
        self.tmpre_s = jsonData["tmpre_s"]
        self.auto = jsonData["auto"]

    def sendJsonData(self):
        dat = dict()
        date = datetime.now()
        nowtime = chr(date.hour) + chr(date.minute) + chr(date.second)
        dat['id'] = self.id
        dat['resfeq'] = 1000
        dat['time'] = nowtime
        dat['cmd'] = str(self.cmd)
        self.cmd = None
        return jsonify(dat)

class ESP32CamState:
    def __init__(self, id = None) -> None:
        self.id = None
        self.autofeed = None
        self.feedtime0 = None
        self.feedtime1 = None
        self.feedtime2 = None
        self.feedsize0 = None
        self.feedsize1 = None
        self.feedtime0On = None
        self.feedtime1On = None
        self.feedtime2On = None
        self.cmd = None
    
    def processJsonData(self, jsonData:dict) -> None:
        self.id = jsonData["id"]
        self.autofeed = jsonData["auto"]
        self.feedtime0 = jsonData["time0"]
        self.feedtime1 = jsonData["time1"]
        self.feedtime2 = jsonData["time2"]
        self.feedsize0 = jsonData["size0"]
        self.feedsize1 = jsonData["size1"]
        self.feedtime0On = jsonData["time0On"]
        self.feedtime1On = jsonData["time1On"]
        self.feedtime2On = jsonData["time2On"]

    def sendJsonData(self):
        dat = dict()
        date = datetime.now()
        nowtime = chr(date.hour+ord('0')) + chr(date.minute+ord('0')) + chr(date.second+ord('0'))
        dat['id'] = self.id
        dat['resfeq'] = 1000
        dat['time'] = nowtime
        dat['cmd'] = str(self.cmd)
        self.cmd = None
        return jsonify(dat)

ESP32 = ESP32State()
ESP32Cam = ESP32CamState()

@app.route('/')
def index():
	return render_template("index.html", ESP32 = ESP32)

@app.route("/ctrl/<cmd>", methods = ['POST'])
def moist_ctrl(cmd):
    ESP32.cmd = cmd
    return redirect(url_for("index", ESP32 = ESP32))

@app.route('/echo', methods=['POST'])  
def echo():
    data = request.get_json()
    '''返回数据'''
    if data["ESP32request"]==1:
        ESP32.processJsonData(data)
        dat = ESP32.sendJsonData()
        ESP32.cmd = None
    else:
        dat = jsonify({"err":"not ESP32"})
    return dat

''' 模拟发送页 '''
@app.route('/send', methods=['GET'])  
def send():
    # 创建一个 test_client 对象
    client = app.test_client()

    # 返回虚拟数据
    data = {'ESP32request':1}
    data["id"] = 1
    data["moist"] = 13
    data["moist_s"] = 1
    data["light"] = 13
    data["light_s"] = 1
    data["tmpre"] = 27
    data["tmpre_s"] = 0
    data["auto"] = 0

    # 使用 test_client 对象模拟发送 POST 请求到 /echo 路由，并将数据作为 JSON 格式发送
    response = client.post('/echo', data=json.dumps(data), content_type='application/json')

    # 返回 /echo 路由的响应数据
    return response.data.decode('utf-8')

''' SC标题页 '''
@app.route("/SC")
def SCIndex():
    return render_template("SC_index.html", ESP32Cam = ESP32Cam, date = datetime.now())

@app.route("/SC/get-image/<i>")
def get_image(i):
    image_path = 'static\\uploads\\456'
    return send_file(image_path, as_attachment=True)

@app.route("/SC/ctrl", methods = ['POST'])
def SC_ctrl():
    data = request.get_json()
    if(data.get("cmd")):
        ESP32Cam.cmd = data["cmd"]
        return jsonify(message='Key status updated')
    else:
        return jsonify(message='Invalid request'), 400

''' SC标题页 '''
@app.route("/SC/getdate", methods=['POST'])
def SC_getdata():
    return jsonify({'date' : datetime.now(), 'ESP32Cam' : json.dumps(ESP32Cam.__dict__)})

''' 真实接收页 '''
@app.route('/SC/echo', methods=['POST'])  
def SCecho():
    data = request.get_json()
    '''返回数据'''
    if data["ESP32request"]==1:
        ESP32Cam.processJsonData(data) # 将data的数据存到ESP32Cam类中
        dat = ESP32Cam.sendJsonData() # 从类中拿出数据给dat
    else:
        dat = jsonify({"err":"not ESP32"}) # 发送数据
    return dat

''' 模拟发送页 '''
@app.route('/SC/send', methods=['GET'])  
def SCsend():
    # 创建一个 test_client 对象
    client = app.test_client()

    # 返回虚拟数据
    data = {'ESP32request':1}
    data["id"] = 1
    data["auto"] = True
    data["time0"] = "08:00:00"
    data["time1"] = "12:00:00"
    data["time2"] = "18:00:00"
    data["size0"] = 5
    data["size1"] = 2
    data["time0On"] = False
    data["time1On"] = False
    data["time2On"] = False

    # 使用 test_client 对象模拟发送 POST 请求到 /echo 路由，并将数据作为 JSON 格式发送
    response = client.post('/SC/echo', data=json.dumps(data), content_type='application/json')

    # 返回 /echo 路由的响应数据
    return response.data.decode('utf-8')

@app.route('/t')
def tindex():
    return render_template('t.html')

@app.route('/t', methods=['POST'])
def upload_file():
    name = request.form['filename']
    print(name)
    file = request.files['file_in_t'] # 根据input表单中的<name="file_in_t">接收文件 file 的数据
    if file:
    # if 1:
        basepath = os.path.dirname(__file__) # 获取app.py的路径
        filename = secure_filename(name) # 给文件起名
        filelocationandname = os.path.join(basepath, 'static/uploads', filename) # 根据app.py获取存储的目标路径
        file.save(filelocationandname) # 按存储路径和名称存储文件file
        return redirect(f'/uploads/{filename}') # 重导航至新的路由

@app.route('/uploads/<filename>')
def display_file(filename):
    # filename = "uploads/" + filename
    return render_template('tdisplay.html', filename=filename) # 直接传文件名，在html中再读取路径

if __name__=='__main__':
	app.run(debug = True)
